package cn.demoncat.util.lang;

import cn.demoncat.util.lang.constant.DateConstant;
import cn.demoncat.util.lang.constant.LongConstant;
import cn.demoncat.util.lang.constant.ReportConstant;
import cn.demoncat.util.lang.constant.ReportConstant.ModeTime;
import cn.demoncat.util.lang.constant.StringConstant;
import cn.demoncat.util.lang.entity.report.*;
import cn.demoncat.util.lang.fn.Consumer2;
import cn.demoncat.util.lang.fn.Consumer3;
import cn.demoncat.util.lang.fn.Function2;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.Month;
import java.util.*;
import java.util.function.Function;

/**
 * 报表数据工具
 * 
 * @author 延晓磊
 *
 * @since 2019年12月11日
 */
public final class ReportUtil {



	/**
	 * 分时图表：单维度 count
	 * 
	 * @param param		图表参数
	 * @param datas		查询结果
	 * 
	 * @return {category,value}
	 * 
	 * @author 延晓磊
	 *
	 * @since 2019年12月11日
	 */
	public static <T extends ReportEntity>ReportDataTimeCount getTimeChartCount(ReportParamChartTime param, List<T> datas){
		// 图表
		ReportDataTimeCount result = new ReportDataTimeCount();
		// 处理
		timeChartHandle(result, param, datas, null, (i,t) -> {
			if (t == null) {
				// 默认值
				result.getValue().add(LongConstant.N0);
			}else if (i == null) {
				// 添加
				result.getValue().add(t.getCount());
			}else {
				// 修改
				result.getValue().set(i, t.getCount());
			}
		});
		return result;
	}
	
	/**
	 * 分时图表：单维度 sum
	 * 
	 * @param param		图表参数
	 * @param datas		查询结果
	 * 
	 * @return {category,value}
	 * 
	 * @author 延晓磊
	 *
	 * @since 2019年12月11日
	 */
	public static <T extends ReportEntity>ReportDataTimeSum getTimeChartSum(ReportParamChartTime param, List<T> datas){
		// 图表
		ReportDataTimeSum result = new ReportDataTimeSum();
		// 处理
		timeChartHandle(result, param, datas, null, (i,t) -> {
			if (t == null) {
				// 默认值
				result.getValue().add(BigDecimal.ZERO);
			}else if (i == null) {
				// 添加
				result.getValue().add(t.getSum());
			}else {
				// 修改
				result.getValue().set(i, t.getSum());
			}
		});
		return result;
	}
	
	/**
	 * 分时图表：双维度 count,sum
	 * 
	 * @param param		图表参数
	 * @param datas		查询结果
	 * 
	 * @return {category,value,legend[countTitle,sumTitle]}
	 * 
	 * @author 延晓磊
	 *
	 * @since 2019年12月11日
	 */
	public static <T extends ReportEntity>ReportDataTimeCountSum getTimeChartCountSum(ReportParamChartTime param, List<T> datas, String countTitle, String sumTitle){
		// 图表
		ReportDataTimeCountSum result = new ReportDataTimeCountSum(countTitle,sumTitle);
		List<Object> countValues = result.getValues(countTitle);
		List<Object> sumValues = result.getValues(sumTitle);
		// 处理
		timeChartHandle(result, param, datas, null, (i,t) -> {
			if (t == null) {
				// 默认值
				countValues.add(LongConstant.N0);
				sumValues.add(BigDecimal.ZERO);
			}else if (i == null) {
				// 添加
				countValues.add(t.getCount());
				sumValues.add(t.getSum());
			}else {
				// 修改
				countValues.set(i, t.getCount());
				sumValues.set(i, t.getSum());
			}
		});
		return result;
	}
	
	/**
	 * 分时图表：多维度 count
	 * 
	 * @param param		图表参数
	 * @param datas		查询结果
	 * @param items		维度映射：{item:title}，如果为空则获取{data.item:data.title}
	 * 
	 * @return {category,value,legend[title]}
	 * 
	 * @author 延晓磊
	 *
	 * @since 2019年12月11日
	 */
	public static <T extends ReportEntity>ReportDataTimeCounts getTimeChartCounts(ReportParamChartTime param, List<T> datas, Map<String, String> items){
		// 维度
		Map<String, String> itemMap = checkItemMap(datas, items);
		// 图表
		ReportDataTimeCounts result = new ReportDataTimeCounts(itemMap.values());
		// 处理
		timeChartHandle(result, param, datas, itemMap, (i,t) -> {
			if (t == null) {
				// 默认值
				for (List<Long> val : result.getValue().values()) {
					val.add(LongConstant.N0);
				}
			}else if (i == null) {
				// 添加
			}else {
				// 修改
				result.getValues(itemMap.get(t.getItem())).set(i, t.getCount());
			}
		});
		return result;
	}
	
	/**
	 * 分时图表：多维度 count
	 * 
	 * @param param		图表参数
	 * @param datas		查询结果
	 * @param items		维度列表：[item]，如果为空则获取[data.item]
	 * 
	 * @return {category,value,legend[item]}
	 * 
	 * @author 延晓磊
	 *
	 * @since 2019年12月11日
	 */
	public static <T extends ReportEntity>ReportDataTimeCounts getTimeChartCounts2(ReportParamChartTime param, List<T> datas, List<String> items){
		return getTimeChartCounts(param, datas, toItemMap(datas, items));
	}
	
	/**
	 * 分时图表：多维度 sum
	 * 
	 * @param param		图表参数
	 * @param datas		查询结果
	 * @param items		维度映射：{item:title}，如果为空则获取{data.item:data.title}
	 * 
	 * @return {category,value,legend[title]}
	 * 
	 * @author 延晓磊
	 *
	 * @since 2019年12月11日
	 */
	public static <T extends ReportEntity>ReportDataTimeSums getTimeChartSums(ReportParamChartTime param, List<T> datas, Map<String, String> items){
		// 维度
		Map<String, String> itemMap = checkItemMap(datas, items);
		// 图表
		ReportDataTimeSums result = new ReportDataTimeSums(itemMap.values());
		// 处理
		timeChartHandle(result, param, datas, itemMap, (i,t) -> {
			if (t == null) {
				// 默认值
				for (List<BigDecimal> val : result.getValue().values()) {
					val.add(BigDecimal.ZERO);
				}
			}else if (i == null) {
				// 添加
			}else {
				// 修改
				result.getValues(itemMap.get(t.getItem())).set(i, t.getSum());
			}
		});
		return result;
	}
	
	/**
	 * 分时图表：多维度 sum
	 * 
	 * @param param		图表参数
	 * @param datas		查询结果
	 * @param items		维度列表：[item]，如果为空则获取[data.item]
	 * 
	 * @return {category,value,legend[item]}
	 * 
	 * @author 延晓磊
	 *
	 * @since 2019年12月11日
	 */
	public static <T extends ReportEntity>ReportDataTimeSums getTimeChartSums2(ReportParamChartTime param, List<T> datas, List<String> items){
		return getTimeChartSums(param, datas, toItemMap(datas, items));
	}
	
	/**
	 * 分时图表：多维度 field
	 * 
	 * @param param		图表参数
	 * @param datas		查询结果
	 * @param items		维度映射：{field:fieldName}
	 * @param getter	字段获取器：获取数据的field对应的值
	 * 
	 * @return {category,value[通过getter获取],legend[fieldName]}
	 * 
	 * @author 延晓磊
	 *
	 * @since 2019年12月11日
	 */
	public static <T extends ReportEntity>ReportDataTimeField getTimeChartField(ReportParamChartTime param, List<T> datas, Map<String, String> items, Function2<T, String, Object> getter){
		// 图表
		ReportDataTimeField result = new ReportDataTimeField(items.values());
		// 处理
		timeChartHandle(result, param, datas, items, (i,t) -> {
			if (t == null) {
				// 默认值
				for (List<String> val : result.getValue().values()) {
					val.add(StringConstant.N0);
				}
			}else if (i == null) {
				// 添加
			}else {
				// 修改
				for (String item : items.keySet()) {
					// 字段对应的名称 > 名称对应的数据集 > 字段值
					result.getValues(items.get(item)).set(i, StringUtil.toDefault(StringUtil.toString(getter.apply(t, item)), StringConstant.N0));
				}
			}
		});
		return result;
	}
	
	/**
	 * 分时图表：多维度 field
	 * 
	 * @param param		图表参数
	 * @param datas		查询结果
	 * @param items		维度映射：{field:fieldName}
	 * 
	 * @return {category,value[通过field反射获取],legend[fieldName]}
	 * 
	 * @author 延晓磊
	 *
	 * @since 2019年12月11日
	 */
	public static <T extends ReportEntity>ReportDataTimeField getTimeChartField(ReportParamChartTime param, List<T> datas, Map<String, String> items){
		return getTimeChartField(param, datas, items, ReflectFieldUtil::get);
	}
	
	/**
	 * 周期图表：单维度 count
	 * 
	 * @param param		图表参数
	 * @param datas		查询结果
	 * 
	 * @return {category,value}
	 * 
	 * @author 延晓磊
	 *
	 * @since 2019年12月11日
	 */
	public static <T extends ReportEntity> ReportDataPeriodCount getPeriodChartCount(ReportParamChartPeriod param, List<T> datas){
		// 图表
		ReportDataPeriodCount result = new ReportDataPeriodCount();
		// 处理
		periodChartHandle(result, param, datas, null, (i,t,b) -> {
			if (t == null) {
				// 默认值
				result.getValue().add(LongConstant.N0);
			}else if (b) {
				// 合并
				result.getValue().set(i, result.getValue().get(i) + t.getCount());
			}else {
				// 修改
				result.getValue().set(i, t.getCount());
			}
		});
		return result;
	}
	
	/**
	 * 周期图表：单维度 sum
	 * 
	 * @param param		图表参数
	 * @param datas		查询结果
	 * 
	 * @return {category,value}
	 * 
	 * @author 延晓磊
	 *
	 * @since 2019年12月11日
	 */
	public static <T extends ReportEntity>ReportDataPeriodSum getPeriodChartSum(ReportParamChartPeriod param, List<T> datas){
		// 图表
		ReportDataPeriodSum result = new ReportDataPeriodSum();
		// 处理
		periodChartHandle(result, param, datas, null, (i,t,b) -> {
			if (t == null) {
				// 默认值
				result.getValue().add(BigDecimal.ZERO);
			}else if (b) {
				// 合并
				result.getValue().set(i, result.getValue().get(i).add(t.getSum()));
			}else {
				// 修改
				result.getValue().set(i, t.getSum());
			}
		});
		return result;
	}
	
	/**
	 * 周期图表：双维度 count,sum
	 * 
	 * @param param			图表参数
	 * @param datas			查询结果
	 * @param countTitle	count的维度标题
	 * @param sumTitle		sum的维度标题
	 * 
	 * @return {category,value,legend[countTitle,sumTitle]}
	 * 
	 * @author 延晓磊
	 *
	 * @since 2019年12月11日
	 */
	public static <T extends ReportEntity> ReportDataPeriodCountSum getPeriodChartCountSum(ReportParamChartPeriod param, List<T> datas, String countTitle, String sumTitle){
		// 图表
		ReportDataPeriodCountSum result = new ReportDataPeriodCountSum(countTitle,sumTitle);
		List<Object> countValues = result.getValues(countTitle);
		List<Object> sumValues = result.getValues(sumTitle);
		// 处理
		periodChartHandle(result, param, datas, null, (i,t,b) -> {
			if (t == null) {
				// 默认值
				countValues.add(LongConstant.N0);
				sumValues.add(BigDecimal.ZERO);
			}else if (b) {
				// 合并
				countValues.set(i, ((Long)countValues.get(i)) + t.getCount());
				sumValues.set(i, ((BigDecimal)sumValues.get(i)).add(t.getSum()));
			}else {
				// 修改
				countValues.set(i, t.getCount());
				sumValues.set(i, t.getSum());
			}
		});
		return result;
	}
	
	/**
	 * 周期图表：多维度 count
	 * 
	 * @param param		图表参数
	 * @param datas		查询结果
	 * @param items		维度映射：{item:title}，如果为空则获取{data.item:data.title}
	 * 
	 * @return {category,value,legend[title]}
	 * 
	 * @author 延晓磊
	 *
	 * @since 2019年12月11日
	 */
	public static <T extends ReportEntity> ReportDataPeriodCounts getPeriodChartCounts(ReportParamChartPeriod param, List<T> datas, Map<String, String> items){
		// 维度
		Map<String, String> itemMap = checkItemMap(datas, items);
		// 图表
		ReportDataPeriodCounts result = new ReportDataPeriodCounts(itemMap.values());
		// 处理
		periodChartHandle(result, param, datas, itemMap, (i,t,b) -> {
			if (t == null) {
				// 默认值
				for (List<Long> val : result.getValue().values()) {
					val.add(LongConstant.N0);
				}
			}else if (b) {
				// 合并
				result.getValues(itemMap.get(t.getItem())).set(i, result.getValues(itemMap.get(t.getItem())).get(i) + t.getCount());
			}else {
				// 修改
				result.getValues(itemMap.get(t.getItem())).set(i, t.getCount());
			}
		});
		return result;
	}
	
	/**
	 * 周期图表：多维度 count
	 * 
	 * @param param		图表参数
	 * @param datas		查询结果
	 * @param items		维度列表：[item]，如果为空则获取[data.item]
	 * 
	 * @return {category,value,legend[item]}
	 * 
	 * @author 延晓磊
	 *
	 * @since 2019年12月11日
	 */
	public static <T extends ReportEntity>ReportDataPeriodCounts getPeriodChartCounts2(ReportParamChartPeriod param, List<T> datas, List<String> items){
		return getPeriodChartCounts(param, datas, toItemMap(datas, items));
	}
	
	/**
	 * 周期图表：多维度 sum
	 * 
	 * @param param		图表参数
	 * @param datas		查询结果
	 * @param items		维度映射：{item:title}，如果为空则获取{data.item:data.title}
	 * 
	 * @return {category,value,legend[title]}
	 * 
	 * @author 延晓磊
	 *
	 * @since 2019年12月11日
	 */
	public static <T extends ReportEntity>ReportDataPeriodSums getPeriodChartSums(ReportParamChartPeriod param, List<T> datas, Map<String, String> items){
		// 维度
		Map<String, String> itemMap = checkItemMap(datas, items);
		// 图表
		ReportDataPeriodSums result = new ReportDataPeriodSums(itemMap.values());
		// 处理
		periodChartHandle(result, param, datas, itemMap, (i,t,b) -> {
			if (t == null) {
				// 默认值
				for (List<BigDecimal> val : result.getValue().values()) {
					val.add(BigDecimal.ZERO);
				}
			}else if (b) {
				// 合并
				result.getValues(itemMap.get(t.getItem())).set(i, result.getValues(itemMap.get(t.getItem())).get(i).add(t.getSum()));
			}else {
				// 修改
				result.getValues(itemMap.get(t.getItem())).set(i, t.getSum());
			}
		});
		return result;
	}
	
	/**
	 * 周期图表：多维度 sum
	 * 
	 * @param param		图表参数
	 * @param datas		查询结果
	 * @param items		维度列表：[item]，如果为空则获取[data.item]
	 * 
	 * @return {category,value,legend[item]}
	 * 
	 * @author 延晓磊
	 *
	 * @since 2019年12月11日
	 */
	public static <T extends ReportEntity>ReportDataPeriodSums getPeriodChartSums2(ReportParamChartPeriod param, List<T> datas, List<String> items){
		return getPeriodChartSums(param, datas, toItemMap(datas, items));
	}
	
	/**
	 * 周期图表：多维度 field
	 * 
	 * @param param		图表参数
	 * @param datas		查询结果
	 * @param items		维度映射：{field:fieldName}
	 * @param getter	字段获取器：获取数据的field对应的值
	 * 
	 * @return {category,value[通过getter获取],legend[fieldName]}
	 * 
	 * @author 延晓磊
	 *
	 * @since 2019年12月11日
	 */
	public static <T extends ReportEntity>ReportDataPeriodField getPeriodChartField(ReportParamChartPeriod param, List<T> datas, Map<String, String> items, Function2<T, String, Object> getter){
		// 图表
		ReportDataPeriodField result = new ReportDataPeriodField(items.values());
		// 处理
		periodChartHandle(result, param, datas, items, (i,t,b) -> {
			if (t == null) {
				// 默认值
				for (List<String> val : result.getValue().values()) {
					val.add(StringConstant.N0);
				}
			}else if (b) {
				// 合并
				for (String item : items.keySet()) {
					// 字段对应的名称 > 名称对应的数据集 > 字段值合并
					result.getValues(items.get(item)).set(i, DecimalUtil.toString(new BigDecimal(result.getValues(items.get(item)).get(i)).add(new BigDecimal(StringUtil.toDefault(StringUtil.toString(getter.apply(t, item)), StringConstant.N0)))));
				}
			}else {
				// 修改
				for (String item : items.keySet()) {
					// 字段对应的名称 > 名称对应的数据集 > 字段值
					result.getValues(items.get(item)).set(i, StringUtil.toDefault(StringUtil.toString(getter.apply(t, item)), StringConstant.N0));
				}
			}
		});
		return result;
	}
	
	/**
	 * 周期图表：多维度 field
	 * 
	 * @param param		图表参数
	 * @param datas		查询结果
	 * @param items		维度映射：{field:fieldName}
	 * 
	 * @return {category,value[通过field反射获取],legend[fieldName]}
	 * 
	 * @author 延晓磊
	 *
	 * @since 2019年12月11日
	 */
	public static <T extends ReportEntity>ReportDataPeriodField getPeriodChartField(ReportParamChartPeriod param, List<T> datas, Map<String, String> items){
		return getPeriodChartField(param, datas, items, ReflectFieldUtil::get);
	}
	
	/**
	 * 分时图表：多维度 field
	 * 
	 * @param mode		模式：ReportConstant.ModeTimeTime
	 * @param date		基准日期：用于查询历史日期的图表，默认当天（时表）、当月（日表）、当年（月表）
	 * @param condition	数据筛选条件
	 * @param items		维度映射：{field:fieldName}
	 * @param query		数据查询器：分组查询数据，统计多个field的值
	 * @param getter	字段获取器：获取数据的field对应的值
	 * 
	 * @return {category,value[通过getter获取],legend[fieldName]}
	 * 
	 * @author 延晓磊
	 * @return 
	 *
	 * @since 2019年12月11日
	 */
	public static <T extends ReportEntity>ReportDataTimeField getTimeChartField(String mode, ReportTime date, Map<String, Object> condition, Map<String, String> items, Function<Map<String, Object>, List<T>> query, Function2<T, String, Object> getter) {
		// 获取图表参数
		ReportParamChartTime param = ReportParamChartTime.build(mode, date);
		// 整合查询参数
		condition = param.getParams(condition);
		// 查询数据
		List<T> datas = query.apply(condition);
		// 整合图表数据
		return getTimeChartField(param, datas, items, getter);
	}
	
	/**
	 * 分时图表：多维度 field
	 * 
	 * @param mode		模式：ReportConstant.ModeTimeTime
	 * @param date		基准日期：用于查询历史日期的图表，默认当天（时表）、当月（日表）、当年（月表）
	 * @param condition	数据筛选条件
	 * @param items		维度映射：{field:fieldName}
	 * @param query		数据查询器：分组查询数据，统计多个field的值
	 * 
	 * @return {category,value[通过field反射获取],legend[fieldName]}
	 * 
	 * @author 延晓磊
	 * @return 
	 *
	 * @since 2019年12月11日
	 */
	public static <T extends ReportEntity>ReportDataTimeField getTimeChartField(String mode, ReportTime date, Map<String, Object> condition, Map<String, String> items, Function<Map<String, Object>, List<T>> query) {
		return getTimeChartField(mode, date, condition, items, query, ReflectFieldUtil::get);
	}
	
	/**
	 * 周期图表：多维度 field
	 * 
	 * @param mode		模式：ReportConstant.ModePeriod
	 * @param num		周期数
	 * @param date		基准日期(结束周期)，默认当前
	 * @param condition	数据筛选条件
	 * @param items		维度映射：{field:fieldName}
	 * @param query		数据查询器：分组查询数据，统计多个field的值
	 * @param getter	字段获取器：获取数据的field对应的值
	 * 
	 * @return {category,value[通过getter获取],legend[fieldName]}
	 * 
	 * @author 延晓磊
	 * @return 
	 *
	 * @since 2019年12月11日
	 */
	public static <T extends ReportEntity>ReportDataPeriodField getPeriodChartField(String mode, Integer num, LocalDateTime date, Map<String, Object> condition, Map<String, String> items, Function<Map<String, Object>, List<T>> query, Function2<T, String, Object> getter) {
		// 获取图表参数
		ReportParamChartPeriod param = ReportParamChartPeriod.build(mode, num, date);
		// 整合查询参数
		condition = param.getParams(condition);
		// 查询数据
		List<T> list = query.apply(condition);
		// 整合图表数据
		return getPeriodChartField(param, list, items, getter);
	}
	
	/**
	 * 周期图表：多维度 field
	 * 
	 * @param mode		模式：ReportConstant.ModePeriod
	 * @param num		周期数
	 * @param date		基准日期(结束周期)，默认当前
	 * @param condition	数据筛选条件
	 * @param items		维度映射：{field:fieldName}
	 * @param query		数据查询器：分组查询数据，统计多个field的值
	 * 
	 * @return {category,value[通过field反射获取],legend[fieldName]}
	 * 
	 * @author 延晓磊
	 * @return 
	 *
	 * @since 2019年12月11日
	 */
	public static <T extends ReportEntity>ReportDataPeriodField getPeriodChartField(String mode, Integer num, LocalDateTime date, Map<String, Object> condition, Map<String, String> items, Function<Map<String, Object>, List<T>> query) {
		return getPeriodChartField(mode, num, date, condition, items, query, ReflectFieldUtil::get);
	}
	
	/**
	 * 查询图表：多维度 field
	 * 
	 * <pre>
	 * # 图表设置参数
	 * mode		图表模式：ReportConstant.ModeTime/ModePeriod
	 * year		分时图表-筛选时段-年
	 * month	分时图表-筛选时段-月
	 * day		分时图表-筛选时段-日
	 * hour		分时图表-筛选时段-时
	 * date		周期图表-截止时间
	 * num		周期图表-周期数
	 * </pre>
	 * 
	 * @param param			图表设置参数
	 * @param condition		数据筛选条件
	 * @param items			维度映射：{field:fieldName}
	 * @param query			数据查询器：分组查询数据，统计多个field的值
	 * @param getter		字段获取器：获取数据的field对应的值
	 * 
	 * @return ReportDataTimeField/ReportDataPeriodField：{category,value[通过getter获取],legend[fieldName]}
	 * 
	 * @author 延晓磊
	 *
	 * @since 2020年3月6日
	 */
	public static <T extends ReportEntity> ReportData getChartField(ReportParam param, Map<String, Object> condition, Map<String, String> items, Function<Map<String, Object>, List<T>> query, Function2<T, String, Object> getter) {
		// 查询图表
		ParamEmptyUtil.checkBlank(param.getMode());
		if (ModeTime.MODE_TYPE.equals(StringUtil.get(param.getMode(), 0))) {
			// 分时图表
			return getTimeChartField(param.getMode(), new ReportTime(param), condition, items, query, getter);
		}else {
			// 周期图表
			return getPeriodChartField(param.getMode(), param.getNum(), param.getDate(), condition, items, query, getter);
		}
	}
	
	/**
	 * 查询图表：多维度 field
	 * 
	 * <pre>
	 * # 图表设置参数
	 * mode		图表模式：ReportConstant.ModeTime/ModePeriod
	 * year		分时图表-筛选时段-年
	 * month	分时图表-筛选时段-月
	 * day		分时图表-筛选时段-日
	 * hour		分时图表-筛选时段-时
	 * date		周期图表-截止时间
	 * num		周期图表-周期数
	 * </pre>
	 * 
	 * @param param			图表设置参数
	 * @param condition		数据筛选条件
	 * @param items			维度映射：{field:fieldName}
	 * @param query			数据查询器：分组查询数据，统计多个field的值
	 * 
	 * @return ReportDataTimeField/ReportDataPeriodField：{category,value[通过field反射获取],legend[fieldName]}
	 * 
	 * @author 延晓磊
	 *
	 * @since 2020年3月6日
	 */
	public static <T extends ReportEntity>ReportData getChartField(ReportParam param, Map<String, Object> condition, Map<String, String> items, Function<Map<String, Object>, List<T>> query) {
		// 查询图表
		ParamEmptyUtil.checkBlank(param.getMode());
		if (ModeTime.MODE_TYPE.equals(StringUtil.get(param.getMode(), 0))) {
			// 分时图表
			return getTimeChartField(param.getMode(), new ReportTime(param), condition, items, query);
		}else {
			// 周期图表
			return getPeriodChartField(param.getMode(), param.getNum(), param.getDate(), condition, items, query);
		}
	}
	
	
	/**
	 * 转换维度说明 ItemList为ItemMap
	 * 
	 * @param datas	数据
	 * @param items	维度列表：[item]，如果为空则获取[data.item]
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2020年7月9日
	 */
	private static <T extends ReportEntity>Map<String, String> toItemMap(List<T> datas, List<String> items){
		Map<String, String> itemsMap = new LinkedHashMap<>();
		if (items == null || items.isEmpty()) {
			// 默认维度
			for (T data : datas) {
				itemsMap.put(data.getItem(), data.getItem());
			}
		}else {
			// 指定维度
			for (String item : items) {
				itemsMap.put(item, item);
			}
		}
		return itemsMap;
	}
	
	/**
	 * 检查维度说明
	 * 
	 * @param datas	数据
	 * @param items	维度映射，如果为空则获取{data.item:data.title}
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2020年7月9日
	 */
	private static <T extends ReportEntity>Map<String, String> checkItemMap(List<T> datas, Map<String, String> items){
		if (MapUtil.isEmpty(items)) {
			// 默认维度
			items = new HashMap<>();
			for (T data : datas) {
				items.put(data.getItem(), StringUtil.toDefault(data.getTitle(), data.getItem()));
			}
		}
		return items;
	}
	
	/**
	 * 分时图表处理
	 * 
	 * @param result	图表
	 * @param param		图表参数
	 * @param datas		查询数据
	 * @param items		维度说明：多维{item, title}，单维/双维传null
	 * @param consumer	赋值器：(null,null)默认值，(null,t)添加，(i,t)修改
	 * 
	 * @author 延晓磊
	 *
	 * @since 2020年7月9日
	 */
	private static <T extends ReportEntity>void timeChartHandle(ReportDataTime result, ReportParamChartTime param, List<T> datas, Map<String, String> items, Consumer2<Integer,T> consumer){
		// 有数据
		if (param.getMaxValue() >= 0) {
			// 模式
			switch (param.getMode()) {
			case ReportConstant.ModeTime.HOUR:
				// 时
				for (int i = 0; i < 24; i++) {
					// 分组
					result.getCategory().add(i);
					// 默认数据
					if (i <= param.getMaxValue()) {
						consumer.accept(null, null);
					}
				}
				for (T o : datas) {
					// 设置数据
					if (o.getHour() <= param.getMaxValue()) {
						consumer.accept(o.getHour(), o);
					}
				}
				break;
			case ReportConstant.ModeTime.DAY:
				// 日
				for (int i = 1; i <= Month.of(param.getMonth()).maxLength(); i++) {
					// 分组
					result.getCategory().add(i);
					// 默认数据
					if (i <= param.getMaxValue()) {
						consumer.accept(null, null);
					}
				}
				for (T o : datas) {
					// 设置数据
					if (o.getDay() <= param.getMaxValue()) {
						consumer.accept(o.getDay()-1, o);
					}
				}
				break;
			case ReportConstant.ModeTime.MONTH:
				// 月
				for (int i = 1; i <= 12; i++) {
					// 分组
					result.getCategory().add(i);
					// 默认数据
					if (i <= param.getMaxValue()) {
						consumer.accept(null, null);
					}
				}
				for (T o : datas) {
					// 设置数据
					if (o.getMonth() <= param.getMaxValue()) {
						consumer.accept(o.getMonth()-1, o);
					}
				}
				break;
			case ReportConstant.ModeTime.YEAR:
				// 年
				if (items == null) {
					// 单维/双维
					for (T o : datas) {
						// 分组
						result.getCategory().add(o.getYear());
						// 添加数据
						consumer.accept(null, o);
					}
				}else {
					// 多维
					Set<Integer> years = new HashSet<>();
					for (T o : datas) {
						years.add(o.getYear());
					}
					// 分组
					result.addCategory(years);
					// 默认数据
					for (int i=0; i< result.getCategory().size(); i++) {
						consumer.accept(null, null);
					}
					// 设置数据
					for (T o : datas) {
						consumer.accept(result.getCategory().indexOf(o.getYear()), o);
					}
				}
				break;
			default:
				throw ReportConstant.CHART_MODE_ERROR;
			}
		}
	}
	
	/**
	 * 周期图表处理
	 * 
	 * @param result	图表
	 * @param param		图表参数
	 * @param datas		查询数据
	 * @param items		维度说明：多维{item, title}，单维/双维传null
	 * @param consumer	赋值器：(null,null,?)默认值，(i,t,false)修改，(i,t,true)合并修改
	 * 
	 * @author 延晓磊
	 *
	 * @since 2020年7月9日
	 */
	private static <T extends ReportEntity>void periodChartHandle(ReportDataPeriod result, ReportParamChartPeriod param, List<T> datas, Map<String, String> items, Consumer3<Integer,T,Boolean> consumer){
		// 模式
		Map<String,Integer> cache = new HashMap<>();
		String key;
		switch (param.getMode()) {
		case ReportConstant.ModePeriod.HOUR:
			// 时
			for (int i = 0; i < param.getNum(); i++) {
				// 默认数据
				consumer.accept(null, null, null);
				// 分组
				key = param.getStartTime().format(DateConstant.DATE_HOUR_FORMAT);
				result.getCategory().add(key);
				// 缓存索引
				cache.put(key, i);
				// 递增时间
				param.setStartTime(param.getStartTime().plusHours(1));
			}
			
			for (T o : datas) {
				// 设置数据
				consumer.accept(cache.get(LocalDateTime.of(o.getYear(), o.getMonth(), o.getDay(), o.getHour(), 0).format(DateConstant.DATE_HOUR_FORMAT)), o, false);
			}
			break;
		case ReportConstant.ModePeriod.DAY:
			// 日
			for (int i = 0; i < param.getNum(); i++) {
				// 默认数据
				consumer.accept(null, null, null);
				// 分组
				key = param.getStartTime().format(DateConstant.DATE_FROMAT);
				result.getCategory().add(key);
				// 缓存索引
				cache.put(key, i);
				// 递增时间
				param.setStartTime(param.getStartTime().plusDays(1));
			}
			
			for (T o : datas) {
				// 设置数据
				consumer.accept(cache.get(LocalDate.of(o.getYear(), o.getMonth(), o.getDay()).format(DateConstant.DATE_FROMAT)), o, false);
			}
			break;
		case ReportConstant.ModePeriod.MONTH:
			// 月
			for (int i = 0; i < param.getNum(); i++) {
				// 默认数据
				consumer.accept(null, null, null);
				// 分组
				key = param.getStartTime().format(DateConstant.MONTH_FORMAT);
				result.getCategory().add(key);
				// 缓存索引
				cache.put(key, i);
				// 递增时间
				param.setStartTime(param.getStartTime().plusMonths(1));
			}
			
			for (T o : datas) {
				// 设置数据
				consumer.accept(cache.get(LocalDate.of(o.getYear(), o.getMonth(), 1).format(DateConstant.MONTH_FORMAT)), o, false);
			}
			break;
		case ReportConstant.ModePeriod.YEAR:
			// 年
			for (int i = 0; i < param.getNum(); i++) {
				// 默认数据
				consumer.accept(null, null, null);
				// 分组
				key = String.valueOf(param.getStartTime().getYear());
				result.getCategory().add(key);
				// 缓存索引
				cache.put(key, i);
				// 递增时间
				param.setStartTime(param.getStartTime().plusYears(1));
			}
			
			for (T o : datas) {
				// 设置数据
				consumer.accept(cache.get(String.valueOf(o.getYear())), o, false);
			}
			break;
		case ReportConstant.ModePeriod.WEEK:
			// 周
			for (int i = 0; i < param.getNum(); i++) {
				// 默认数据
				consumer.accept(null, null, null);
				// 分组
				key = param.getStartTime().format(DateConstant.DATE_FROMAT);
				result.getCategory().add(key);
				// 缓存索引
				cache.put(key, i);
				// 递增时间
				param.setStartTime(param.getStartTime().plusWeeks(1));
			}
			
			for (T o : datas) {
				// 设置数据：合并日数据
				consumer.accept(cache.get(LocalDateUtil.startOfWeek(LocalDate.of(o.getYear(), o.getMonth(), o.getDay()).atStartOfDay()).format(DateConstant.DATE_FROMAT)), o, true);
			}
			break;
		case ReportConstant.ModePeriod.QUARTER:
			// 季
			for (int i = 0; i < param.getNum(); i++) {
				// 默认数据
				consumer.accept(null, null, null);
				// 分组
				key = param.getStartTime().format(DateConstant.MONTH_FORMAT);
				result.getCategory().add(key);
				// 缓存索引
				cache.put(key, i);
				// 递增时间
				param.setStartTime(LocalDateUtil.plusQuarter(param.getStartTime(), 1));
			}
			
			for (T o : datas) {
				// 设置数据：合并月数据
				consumer.accept(cache.get(LocalDateUtil.startOfQuarter(LocalDate.of(o.getYear(), o.getMonth(), 1).atStartOfDay()).format(DateConstant.MONTH_FORMAT)), o, true);
			}
			break;
		default:
			throw ReportConstant.CHART_MODE_ERROR;
		}
	}
	
}
